﻿using System;
using System.Collections.Generic;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using TrinityAPI.Base.Tools;

namespace TrinityAPI.Base.Models
{
    public class RuntimeData
    {
        private bool _first;
        private string _cursor;
        private JObject _data;

        public string Cursor
        {
            get { return _cursor; }
        }
        public JObject Data
        {
            get { return _data; }
        }

        public RuntimeData(string cursor, JObject data, bool first)
        {
            _first = first;
            _cursor = cursor;
            _data = data;
        }

        public void SetCursor(string cursor)
        {
            if (_data != null)
            {
                _cursor = cursor;
                _data["cursor"] = cursor;
            }
        }

        public void Clear()
        {
            if (_first && _data != null && _data.Parent != null && _data.Parent.Parent != null)
            {
                _data.Parent.Remove();
            }
        }

        public static string RuntimeRoot = "runtimedata";
        public static RuntimeData GetData(JObject dataset, JToken data = null)
        {
            var first = false;
            var cursor = "data";
            var runtimedata = dataset.GetJsonObject(RuntimeRoot);
            if (runtimedata == null)
            {
                if (data == null)
                    return null;
                first = true;
                runtimedata = new JObject()
                {
                    { "cursor", cursor },
                    { "data", data }
                };
                dataset.Add(RuntimeRoot, runtimedata);
            }
            else
            {
                cursor = runtimedata.GetJsonObjectStringValue("cursor");
                if (data != null)
                {
                    if (cursor.EndsWith("]"))
                    {
                        int lastBracketIndex = cursor.LastIndexOf('[');
                        if (lastBracketIndex > 0)
                        {
                            var runTimeData = Utils.GetValueByPath(cursor.Substring(0, lastBracketIndex), runtimedata);
                            if (runTimeData != null && runTimeData.Type == JTokenType.Array)
                            {
                                var index = TypeConverter.StrToInt(cursor.Substring(lastBracketIndex + 1, cursor.Length - lastBracketIndex - 2));
                                var list = runTimeData as JArray;
                                if (list.Count > index)
                                    list[index] = data;
                                else
                                    list.Add(data);
                            }
                        }
                    }
                    else
                    {
                        int lastDotIndex = cursor.LastIndexOf('.');
                        if (lastDotIndex > 0)
                        {
                            var runTimeData = Utils.GetValueByPath(cursor.Substring(0, lastDotIndex), runtimedata);
                            if (runTimeData != null && runTimeData.Type == JTokenType.Object)
                            {
                                var key = cursor.Substring(lastDotIndex + 1);
                                runTimeData[key] = data;
                            }
                        }
                    }
                }
            }
            return new RuntimeData(cursor, runtimedata, first);
        }
    }
}
